//
//  LNCollectionViewController.m
//  LNDevelopExample
//
//  Created by wwww on 2018/9/28.
//  Copyright © 2018年 淘发现1iOS. All rights reserved.
//

#import "LNCollectionViewController.h"

@interface LNCollectionViewController ()<UICollectionViewDelegate,UICollectionViewDataSource,DZNEmptyDataSetSource,DZNEmptyDataSetDelegate,UIScrollViewDelegate>
//viewModel
@property (nonatomic,readwrite,strong) LNCollectionViewModel *viewModel;
//内容缩进
@property (nonatomic,readwrite,assign) UIEdgeInsets contentInsets;
//UICollectionView
@property (nonatomic,readwrite,weak) UICollectionView *collectionView;
@end

@implementation LNCollectionViewController

@dynamic viewModel;

-(void)dealloc{

_collectionView.delegate = nil;
_collectionView.dataSource = nil;
}

-(instancetype)initWithViewModel:(LNViewModel *)viewModel{

self = [super initWithViewModel:viewModel];
if (self) {
    if([viewModel shouldRequestRemoteDataOnViewDidLoad]){
        @weakify(self);
        [[self rac_signalForSelector:@selector(viewDidLoad)] subscribeNext:^(id x) {
            @strongify(self)
            /// 请求第一页的网络数据
            [self.viewModel.requestRemoteDataCommand execute:@1];
        }];
    }
}
return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //设置子控件
    [self setupSubViews];
    //添加刷新控件
    [self addRefresh];
}

// override
-(void)bindViewModel{
    
    [super bindViewModel];
    
    @weakify(self)
    [[RACObserve(self.viewModel, dataSource) deliverOnMainThread] subscribeNext:^(id x) {
        @strongify(self)
        // 刷新数据
        [self reloadData];
    }];
    
    /// 隐藏emptyView
    [self.viewModel.requestRemoteDataCommand.executing subscribeNext:^(NSNumber *executing) {
        @strongify(self)
        UIView *emptyDataSetView = [self.collectionView.subviews.rac_sequence objectPassingTest:^(UIView *view) {
            return [NSStringFromClass(view.class) isEqualToString:@"DZNEmptyDataSetView"];
        }];
        emptyDataSetView.alpha = 1.0 - executing.floatValue;
    }];
    
//    [self.viewModel.requestRemoteDataCommand.executionSignals.switchToLatest subscribeNext:^(id _) {
//        @strongify(self);
//        /// 有网络
//        self.viewModel.disableNetwork = NO;
//    }];
//
//    [self.viewModel.requestRemoteDataCommand.errors subscribeNext:^(id _) {
//        @strongify(self);
//        /// 有无网络
//        self.viewModel.disableNetwork = !self.viewModel.services.client.reachabilityManager.reachable;
//    }];
}

#pragma makr - 设置子控件
-(void)setupSubViews{
    
    UICollectionViewFlowLayout *layout = [UICollectionViewFlowLayout new];
    layout.minimumLineSpacing = self.viewModel.minimumLineSpacing;
    layout.minimumInteritemSpacing = self.viewModel.minimumInteritemSpacing;
    
    UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:[UIScreen mainScreen].bounds collectionViewLayout:layout];
    collectionView.backgroundColor = self.view.backgroundColor;
    
    collectionView.delegate = self;
    collectionView.dataSource = self;
    
    collectionView.emptyDataSetSource   = self;
    collectionView.emptyDataSetDelegate  = self;
    
    [self.view addSubview:collectionView];
    
    [collectionView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.mas_equalTo(UIEdgeInsetsZero);
    }];
    
    self.collectionView = collectionView;
    collectionView.contentInset  = self.contentInset;
    // 注册cell
    [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"UICollectionViewCell"];
    
    if (@available(iOS 11.0, *)) {
        /// CoderMikeHe: 适配 iPhone X + iOS 11，
        LNAdjustsScrollViewInsets_Never(collectionView);
        /// iOS 11上发生tableView顶部有留白，原因是代码中只实现了heightForHeaderInSection方法，而没有实现viewForHeaderInSection方法。那样写是不规范的，只实现高度，而没有实现view，但代码这样写在iOS 11之前是没有问题的，iOS 11之后应该是由于开启了估算行高机制引起了bug。
        //        collectionView.estimatedRowHeight = 0;
        //        collectionView.estimatedSectionHeaderHeight = 0;
        //        collectionView.estimatedSectionFooterHeight = 0;
    }
}

#pragma makr - 添加上下拉刷新
-(void)addRefresh{
    
    //判断是否添加下拉刷新
    if(self.viewModel.shouldPullDownToRefresh){
        @weakify(self);
        [self.collectionView ln_addHeaderRefresh:^(MJRefreshNormalHeader *header) {
            //加载数据
            @strongify(self);
            [self tableViewDidTriggerHeaderRefresh];
        }];
        [self.collectionView.mj_header beginRefreshing];
    }
    
    //判断是否添加上拉刷新
    if (self.viewModel.shouldPullUpToLoadMore) {
        @weakify(self);
        [self.collectionView ln_addFooterRefresh:^(MJRefreshAutoNormalFooter *footer) {
            @strongify(self);
            [self tableViewDidTriggerFooterRefresh];
        }];
    }
    
    //隐藏footer or 无更多数据
    @weakify(self);
    RAC(self.collectionView.mj_footer,hidden) = [[RACObserve(self.viewModel, dataSource) deliverOnMainThread] map:^id(NSArray *dataSoure) {
        @strongify(self);
        NSUInteger count = 0;
        if(self.viewModel.shouldMultiSections){
            //多段
            for (NSArray *array in dataSoure) {
                count += array.count;
            }
        }else{
            //一段
            count = dataSoure.count;
        }
        //无数据
        if (count == 0) {
            return @1;
        }
        if(self.viewModel.shouldEndRefreshingWithNoMoreData)
            return @0;
        /// because of
        return count % self.viewModel.perPage?@1:@0;
    }];
}

#pragma mark - 上下拉刷新事件
/// 下拉事件
- (void)tableViewDidTriggerHeaderRefresh{
    
    @weakify(self)
    [[[self.viewModel.requestRemoteDataCommand execute:@1] deliverOnMainThread] subscribeNext:^(id x) {
        @strongify(self)
        self.viewModel.page = 1;
        /// 重置没有更多的状态
        if (self.viewModel.shouldEndRefreshingWithNoMoreData) [self.collectionView.mj_footer resetNoMoreData];
    } error:^(NSError *error) {
        [self.collectionView.mj_header endRefreshing];
    } completed:^{
        [self.collectionView.mj_header endRefreshing];
        /// 请求完成
        [self requestDataCompleted];
    }];
}

/// 上拉事件
- (void)tableViewDidTriggerFooterRefresh{
    
    @weakify(self);
    [[[self.viewModel.requestRemoteDataCommand
       execute:@(self.viewModel.page + 1)]
      deliverOnMainThread]
     subscribeNext:^(id x) {
         @strongify(self)
         self.viewModel.page += 1;
     } error:^(NSError *error) {
         @strongify(self);
         [self.collectionView.mj_footer endRefreshing];
     } completed:^{
         @strongify(self)
         [self.collectionView.mj_footer endRefreshing];
         /// 请求完成
         [self requestDataCompleted];
     }];
}

#pragma mark - 辅助方法
- (void)requestDataCompleted
{
    NSUInteger count = 0;
    if(self.viewModel.shouldMultiSections){
        /// 多段
        for (NSArray *array in self.viewModel.dataSource) { count += array.count; }
    }else{
        /// 一段
        count = self.viewModel.dataSource.count;
    }
    /// CoderMikeHe Fixed: 这里必须要等到，底部控件结束刷新后，再来设置无更多数据，否则被叠加无效
    if (self.viewModel.shouldEndRefreshingWithNoMoreData && count%self.viewModel.perPage) [self.collectionView.mj_footer endRefreshingWithNoMoreData];
}

#pragma mark - sub class can override it
- (UIEdgeInsets)contentInset{
    return UIEdgeInsetsMake(0, 0, 0, 0);
}

/// reload tableView data
- (void)reloadData{
    [self.collectionView reloadData];
}

/// duqueueReusavleCell
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView dequeueReusableCellWithReuseIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath {
    return [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
}

/// configure cell data
- (void)configureCell:(UICollectionViewCell *)cell atIndexPath:(NSIndexPath *)indexPath withObject:(id)object {}

#pragma mark - UICollectionViewDataSource
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
    
    if (self.viewModel.shouldMultiSections) return self.viewModel.dataSource ? self.viewModel.dataSource.count : 0;
    return 1;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    
    if (self.viewModel.shouldMultiSections) return [self.viewModel.dataSource[section] count];
    return self.viewModel.dataSource.count;
}

- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    
    UICollectionViewCell *cell = [self collectionView:collectionView dequeueReusableCellWithReuseIdentifier:@"UICollectionViewCell" forIndexPath:indexPath];
    
    // fetch object
    id object = nil;
    if (self.viewModel.shouldMultiSections) object = self.viewModel.dataSource[indexPath.section];
    if (!self.viewModel.shouldMultiSections) object = self.viewModel.dataSource[indexPath.row];
    
    /// bind model
    [self configureCell:cell atIndexPath:indexPath withObject:(id)object];
    return cell;
}

#pragma mark - UICollectionViewDelegate
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
    // execute commond
    [self.viewModel.didSelectCommand execute:indexPath];
}

#pragma mark - DZNEmptyData

- (UIImage *)imageForEmptyDataSet:(UIScrollView *)scrollView
{
    //[[WTKNetWork shareInatance] initNetWork];
    if (self.viewModel.disableNetwork)
    {
        return [UIImage imageNamed:@"list_icon_lose"];
    }
    return [UIImage imageNamed:@"list_icon_goto"];
}

- (NSAttributedString *)descriptionForEmptyDataSet:(UIScrollView *)scrollView
{
    NSString *titlestr;
    if (self.viewModel.disableNetwork)
    {
        titlestr = @"网络不好";
    }
    else
        titlestr =@"暂时没有数据哟~";
    
    NSMutableAttributedString *allNumAttr = [[NSMutableAttributedString alloc]initWithString:titlestr];
    allNumAttr.yy_alignment = NSTextAlignmentCenter;
    allNumAttr.yy_maximumLineHeight = 30;
    allNumAttr.yy_font = LNRegularFont_13;
    
    return allNumAttr;
}

- (void)emptyDataSet:(UIScrollView *)scrollView didTapView:(UIView *)view
{
    
    [self.collectionView.mj_header beginRefreshing];
}

//是否允许滚动，默认NO
- (BOOL)emptyDataSetShouldAllowScroll:(UIScrollView *)scrollView {
    return YES;
}
@end
